package fun.sanguo.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * 获取RSA密钥对
 *
 * @author ZYP
 * @date 2022-07-20
 */
public class RSAUtils {

    protected static Logger logger = LoggerFactory.getLogger(RSAUtils.class);

    // 密钥长度，DH算法的默认密钥长度是1024 密钥长度必须是64的倍数，在512到65536位之间
    private static final int KEY_SIZE = 512;
    // 公钥
    private static final String PUBLIC_KEY = "RSAPublicKey";
    // 私钥
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    // 密钥对
    private static Map<String, Object> keyMap = null;

    /**
     * 初始化密钥对
     *
     * @return
     */
    public static void initKey() {
        try {
            // 实例化密钥生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥生成器
            keyPairGenerator.initialize(KEY_SIZE);
            // 生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            // 公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            // 私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 初始化keyMap
            keyMap = new HashMap<>();
            // 将密钥存储在map中
            keyMap.put(PUBLIC_KEY, publicKey);
            keyMap.put(PRIVATE_KEY, privateKey);
        } catch (Exception e) {
            logger.error("初始化密钥对过程中发生异常，exception={}", e.getMessage());
        }
    }

    /**
     * 取得私钥
     *
     * @return
     */
    public static byte[] getPrivateKey() {
        if (keyMap == null) {
            initKey();
        }
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return key.getEncoded();
    }

    /**
     * 取得公钥
     *
     * @return
     */
    public static byte[] getPublicKey() {
        if (keyMap == null) {
            initKey();
        }
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return key.getEncoded();
    }
}